﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SPIWareMVVM.ViewModels;
using System.Windows.Input;
using System.Reflection;
using System.Threading;

namespace SPIWareMVVM.Views.Commands
{
    public class BaseCommand : ICommand
    {
        private readonly Action<object> _Execute;
        private readonly Predicate<object> _CanExecute;
        private bool _IsAuthorized;

        public SPIWareMVVM.Views.Window1 mainWindow { get; set; }
        public BaseViewModel _sender { get; set; }

        public BaseCommand(BaseViewModel sender)
        {
            _sender = sender;

            _Execute = Execute;
            _CanExecute = CanExecute;

            _IsAuthorized = IsAuthorized(_Execute.Method);
        }
        #region ICommand Members
        public bool CanExecute(object parameter)
        {
            if (_IsAuthorized)
            {
                //return _CanExecute == null ? true : _CanExecute(parameter);
                return true;
            }
            else
            {
                return false;
            }
        }
        //public event EventHandler CanExecuteChanged;
        public virtual void Execute(object parameter)
        {
            _Execute(parameter);
        }
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
        #endregion
        private bool IsAuthorized(MethodInfo methodInfo)
        {
            bool isAuthorized = true;

            var authorizationAttributes = (AuthorizationAttribute[])methodInfo.GetCustomAttributes(typeof(AuthorizationAttribute), true);

            if (authorizationAttributes.Count() == 0)
            {
                return true;
            }

            foreach (var authorizationAttribute in authorizationAttributes)
            {
                if (authorizationAttribute.AuthorizationType == AuthorizationType.Allow)
                {
                    isAuthorized = Thread.CurrentPrincipal.IsInRole(authorizationAttribute.Role);
                }
                else if (authorizationAttribute.AuthorizationType == AuthorizationType.Deny)
                {
                    isAuthorized = !Thread.CurrentPrincipal.IsInRole(authorizationAttribute.Role);
                }

                if (isAuthorized == false)
                {
                    break;
                }
            }

            return isAuthorized;
        }
    }
}
